package at.fhooe.mcm.logic.sensors;

import at.fhooe.mcm.logic.core.Core;
import at.fhooe.mcm.logic.core.NameService;
import at.fhooe.mcm.logic.core.Service;
import at.fhooe.mcm.logic.event.Event;
import at.fhooe.mcm.logic.event.EventListener;
import at.fhooe.mcm.logic.event.EventManager;
import at.fhooe.mcm.logic.sensors.entities.AirpressureSensor;
import at.fhooe.mcm.logic.sensors.entities.HumiditySensor;
import at.fhooe.mcm.logic.sensors.entities.TemperatureSensor;
import at.fhooe.mcm.logic.sensors.events.SensorAttachEvent;
import at.fhooe.mcm.logic.sensors.events.SensorChangedEvent;
import at.fhooe.mcm.logic.sensors.events.SensorDetachEvent;
import at.fhooe.mcm.logic.sensors.events.SensorRequestEvent;
import at.fhooe.mcm.logic.sensors.events.SensorResponseEvent;

public class SensorFactory implements Service, EventListener
{

	public static final String	NAME	= "core.sensorfactory";
	private Core				m_core;

	public static SensorFactory getInstance(Core _core)
	{
		return (SensorFactory) _core.getService(NAME);
	}
	
	@Override
	public String getName()
	{
		return NAME;
	}

	@Override
	public void initialize(Core _core)
	{
		EventManager.getInstance(_core).addListener(this, SensorAttachEvent.TYPE);
		EventManager.getInstance(_core).addListener(this, SensorDetachEvent.TYPE);
		EventManager.getInstance(_core).addListener(this, SensorChangedEvent.TYPE);
		EventManager.getInstance(_core).addListener(this, SensorRequestEvent.TYPE);
		m_core = _core;
	}

	@Override
	public void handleEvent(Event _event)
	{
		if (_event.isOfType(SensorAttachEvent.TYPE))
		{
			SensorAttachEvent sensorAttach = (SensorAttachEvent) _event;
			createSensor(sensorAttach.getEntityType(), sensorAttach.getSensorName(), sensorAttach.isPublic(),
					sensorAttach.isPull(), sensorAttach.getUpdatePeriod());
		}
		else if (_event.isOfType(SensorDetachEvent.TYPE))
		{
			SensorDetachEvent sensorDetach = (SensorDetachEvent) _event;
			deleteSensor(sensorDetach.getSensorID());
		}
		else if (_event.isOfType(SensorChangedEvent.TYPE))
		{
			SensorChangedEvent sensorChange = (SensorChangedEvent) _event;
			changeSensor(sensorChange.getSensorID(), sensorChange.getName(), sensorChange.isPublic(), sensorChange
					.isPull(), sensorChange.getUpdatePeriod());
		}
		else if (_event.isOfType(SensorRequestEvent.TYPE))
		{
			SensorRequestEvent sensorRequest = (SensorRequestEvent) _event;
			fetchSensorData(sensorRequest.getID());
		}

	}

	private void fetchSensorData(String _id)
	{
		Sensor s = SensorManager.getInstance(m_core).getEntity(_id);

		SensorResponseEvent rse = new SensorResponseEvent(s.getID(), s.getType(), s.getSensorName(), s.isPublic(), s.isPull(), s.getUpdatePeriod());
		EventManager.getInstance(m_core).enqueueEvent(rse);
	}

	private void changeSensor(String _id, String _name, boolean _isPublic, boolean _isPull, int _updatePeriod)
	{
		Sensor s = SensorManager.getInstance(m_core).getEntity(_id);

		s.setSensorName(_name);
		s.setPublic(_isPublic);
		s.setPull(_isPull);
		s.setUpdatePeriod(_updatePeriod);
	}

	private void deleteSensor(String _id)
	{
		SensorManager.getInstance(m_core).removeEntity(_id);
	}

	private void createSensor(String _type, String _name, boolean _isPublic, boolean _isPull, int _updatePeriod)
	{
		String id = NameService.getInstance(m_core).generateName();

		if (_type.equals(TemperatureSensor.TYPE))
		{
			SensorManager.getInstance(m_core).addEntity(
					new TemperatureSensor(m_core, id, _name, _isPublic, _isPull, _updatePeriod));
		}
		else if (_type.equals(AirpressureSensor.TYPE))
		{
			SensorManager.getInstance(m_core).addEntity(
					new AirpressureSensor(m_core, id, _name, _isPublic, _isPull, _updatePeriod));
		}
		else if (_type.equals(HumiditySensor.TYPE))
		{
			SensorManager.getInstance(m_core).addEntity(
					new HumiditySensor(m_core, id, _name, _isPublic, _isPull, _updatePeriod));
		}
	}

	@Override
	public void shutdown(Core core)
	{
		// TODO Auto-generated method stub
		
	}


}
